package me.zhengjie.pay.rest;


import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.service.partnerpayments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Amount;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Payer;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.PrepayWithRequestPaymentResponse;
import me.zhengjie.business.domain.Zhsq;
import me.zhengjie.business.domain.sup.Gsgl;
import me.zhengjie.business.service.GsglService;
import me.zhengjie.config.WechatPayConfig;
import me.zhengjie.inter.service.MpZhsqService;
import me.zhengjie.pay.domain.JjzhWxPayOrders;
import me.zhengjie.pay.service.JjzhWxPayOrdersService;
import me.zhengjie.utils.OrderNoGenerator;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.SecurityUtils;
import me.zhengjie.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;

@RestController
@RequestMapping("/api/wxpay")
public class WxPayController {

    private static final Logger logger = LoggerFactory.getLogger(WxPayController.class);

    @Autowired
    private WechatPayConfig wechatPayConfig;
    @Autowired
    private GsglService gsglService;
    @Autowired
    private MpZhsqService mpZhsqService;
    @Autowired
    private JjzhWxPayOrdersService jjzhWxPayOrdersService;
    private static final String CURRENCY = "CNY";  // 货币单位
    private static final String SIGN_TYPE = "RSA"; // 签名类型

    @PostMapping("/createOrder")
    public ResponseEntity<Object> createOrder(@RequestBody Map<String, String> request) {
        long startTime = System.currentTimeMillis(); // 记录请求开始时间
        String orderNo = null;
        try {
            // 参数校验
            validateRequest(request);

            // 获取请求参数
//            int amount = Integer.parseInt(request.get("amount"));
            Integer amount = wechatPayConfig.getAmount();

            String description = request.get("description");
            String bisZhsqId = request.get("bisZhsqId");
            logger.info("开始处理居家照护申请支付请求，参数：amount={} description={} bisZhsqId={}", amount, description, bisZhsqId);

            Zhsq zhsq = mpZhsqService.queryByBisZhsqId(Long.valueOf(bisZhsqId));
            orderNo = OrderNoGenerator.generate();
            logger.info("生成的订单号：{}", orderNo);

            // 获取企业信息
            // TODO 企业信息暂时写死
            Gsgl gsgl = gsglService.findByBisGsglId(zhsq.getBisPggsId());
            String subMchid = gsgl.getWxmchid();
            logger.info("获取到子商户号：{}", subMchid);

            // 使用微信支付公钥的RSA配置
            Config config = wechatPayConfig.getNotificationConfig();
            JsapiServiceExtension jsapiService = new JsapiServiceExtension.Builder()
                    .config(config)
                    .build();

            // 构建支付请求
            PrepayRequest prepayRequest = createPrepayRequest(amount, description, bisZhsqId, SecurityUtils.getCurrentUsername(), wechatPayConfig.getMchId(), wechatPayConfig.getAppId(), subMchid, orderNo, wechatPayConfig.getNotifyUrl());
            logger.info("构建微信支付请求：{}", prepayRequest);

            // 调用微信支付API生成预支付订单并返回调起支付参数
            PrepayWithRequestPaymentResponse response = jsapiService.prepayWithRequestPayment(prepayRequest, wechatPayConfig.getAppId());
            logger.info("微信支付API返回预支付响应：{}", response);

            // 生成订单数据存储
            saveOrder(bisZhsqId, subMchid, orderNo, amount, description, zhsq);
            logger.info("订单数据已保存，订单号：{}", orderNo);

            // 返回支付参数
            Map<String, String> result = createPaymentResult(response);
            logger.info("返回给前端的支付参数：{}", result);

            long endTime = System.currentTimeMillis();
            logger.info("订单创建完成，耗时：{} ms", endTime - startTime);

            return new ResponseEntity<>(PageUtil.toMpContent(result), HttpStatus.OK);
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            logger.error("创建订单失败，耗时：{} ms，订单号：{}，错误信息：{}", endTime - startTime, orderNo, e.getMessage(), e);
            return new ResponseEntity<>("创建订单失败：" + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    private void validateRequest(Map<String, String> request) {
        if (request == null || StringUtils.isEmpty(request.get("amount")) || StringUtils.isEmpty(request.get("description")) || StringUtils.isEmpty(request.get("bisZhsqId"))) {
            logger.error("请求参数不完整：{}", request);
            throw new IllegalArgumentException("请求参数不完整");
        }
        logger.info("请求参数校验通过：{}", request);
    }

    private PrepayRequest createPrepayRequest(int amount, String description, String bisZhsqId, String openid, String mchId, String spAppid, String subMchid, String orderNo, String notifyUrl) {
        logger.info("创建PrepayRequest对象，参数：amount={} description={} bisZhsqId={} openid={} mchId={} spAppid={} subMchid={} orderNo={} notifyUrl={}",
                amount, description, bisZhsqId, openid, mchId, spAppid, subMchid, orderNo, notifyUrl);

        PrepayRequest prepayRequest = new PrepayRequest();

        Amount amountObj = new Amount();
        amountObj.setTotal(amount);

        Payer payer = new Payer();
        payer.setSpOpenid(openid);
        prepayRequest.setPayer(payer);

        prepayRequest.setSpAppid(spAppid);
        prepayRequest.setSpMchid(mchId);
        prepayRequest.setSubMchid(subMchid);

        prepayRequest.setDescription(description);
        prepayRequest.setOutTradeNo(orderNo);
        prepayRequest.setNotifyUrl(notifyUrl);
        prepayRequest.setAmount(amountObj);

        logger.debug("PrepayRequest构建完成：{}", prepayRequest);
        return prepayRequest;
    }

    private void saveOrder(String bisZhsqId, String subMchid, String orderNo, int amount, String description, Zhsq zhsq) {
        logger.info("保存订单信息，订单号：{}，金额：{}，描述：{}，居家照护申请ID：{}", orderNo, amount, description, bisZhsqId);

        JjzhWxPayOrders order = new JjzhWxPayOrders();
        order.setBisZhsqId(Long.valueOf(bisZhsqId));
        order.setSubMchind(subMchid);
        order.setOrderNo(orderNo);
        order.setAmount(Long.valueOf(amount));
        order.setDescription(description);
        order.setBisZhsqSnryXm(zhsq.getBisZhsqSnryXm());
        order.setBisZhsqSnrySfz(zhsq.getBisZhsqSnrySfz());
        order.setStatus(0L);
        order.setCurrency(CURRENCY);
        order.setCreatedAt(new Timestamp(System.currentTimeMillis()));

        jjzhWxPayOrdersService.create(order);
        logger.info("订单保存成功，订单号：{}", orderNo);
    }

    private Map<String, String> createPaymentResult(PrepayWithRequestPaymentResponse response) {
        logger.info("构建支付参数，响应数据：{}", response);
        Map<String, String> result = new HashMap<>();
        result.put("timeStamp", response.getTimeStamp());
        result.put("nonceStr", response.getNonceStr());
        result.put("package", response.getPackageVal());
        result.put("signType", SIGN_TYPE);
        result.put("paySign", response.getPaySign());
        return result;
    }

}

